import { RESPONSE_CODE_LOADING } from "./system_constant";
import { CodeType, DataType, BdjfResponse, AttributeMapping } from "./type";


export interface ResponseConstructor {
    code:CodeType;
    msg?: string;
    data?:DataType;
    successCode?:CodeType;
}

export class ResponseImpl implements BdjfResponse{
    [key: string]: any;
    code: CodeType;
    msg?: string;
    data?: DataType;
    readonly successCode?:CodeType;

    constructor(res:ResponseConstructor){
        this.code = res.code;
        this.msg = res.msg;
        this.data = res.data;
        this.successCode = res.successCode;
    }

    loading = (data?: DataType):BdjfResponse => {
        this.code = RESPONSE_CODE_LOADING;
        if(data){
            this.data = data;
        }
        return this;
    }

    get success():boolean{
        return this.code === this.successCode;
    }

    get isLoading():boolean{
        return this.code === RESPONSE_CODE_LOADING;
    }

    update = (newRes: BdjfResponse):BdjfResponse=>{
        Object.keys(this).forEach((key:string)=>{
            this[key] = newRes[key];
        })
        return this;
    }

}

export function createLoadingRes(successCode:CodeType,data?:DataType){
    return new ResponseImpl({
        code:RESPONSE_CODE_LOADING,
        data:data,
        successCode:successCode
    })
}

export function createRes(successCode:CodeType,newRes:any,mapping:AttributeMapping){
    const response = new ResponseImpl({
        code:newRes[mapping.code],
        msg:newRes[mapping.msg],
        data:newRes[mapping.data],
        successCode:successCode
    })

    const hasMapKey = [mapping.code,mapping.msg,mapping.data];

    Object.keys(newRes).filter(function(key:string){
        return hasMapKey.indexOf(key) < 0;
    }).forEach((key:string)=>{
        response[key] = newRes[key];
    })

    return response;
}

export function copyRes(oldRes:BdjfResponse){
    return Object.create(oldRes);
}